import socket
import os
import threading
import  sys

class HttpServer(object):
    '''提供web socket提供web服务 '''
    __isRun = True ##允许外界主动关闭提供关闭函数
    __mainThread=None

    def __init__(self,port,logfun=None):
        self.__port =port
        if logfun != None :
            self.__logfun =logfun
        else :
            self.__logfun = self.print_log

        self.__logfun(f'{self.__port}端口创建新的服务器')

        mysocketThread = threading.Thread(target=self.start_server,args=("",port))
        mysocketThread.setDaemon(True)
        mysocketThread.start()
        self.__mainThread = mysocketThread

    def print_log(self, logmsg,err=None):
        print(f"{logmsg}",err)

    def hander_reuqest(self,newsocket , ip_port):
        try:
            recv_data = newsocket.recv(4096)
            self.__logfun(f'新增请求：{recv_data}')
            recv_data = recv_data.decode("utf-8")
            if recv_data == "":
                newsocket.close()
                return

            recv_data = recv_data.split(" ", maxsplit=2)
            url = recv_data[1]
            url = url.replace("..","")
            while url.startswith("/"):
                url=url[1:]

            if url=="":
                url = "index.html"

            self.__logfun(f'请求预处理链接：{url}')

            header = "HTTP/1.1 200 ok\r\n" + "server:conanServer \r\n" + "\r\n"
            try:
                with open(url, "rb") as file:
                    file_data = file.read()
            except Exception as err:
                self.__logfun(f'链接对应静态文件获取失败：{url}',err)
                header = "HTTP/1.1 400 Not Found File\r\n" + "server:conanServer \r\n" + "\r\n"
                file_data ='<!DOCTYPE html><html><head><meta charset="utf-8"><title>出错啦</title></head><body>访问的文件不存在</body></html> '.encode("utf-8")

            content = header.encode("utf-8") + file_data
            newsocket.send(content)
        except Exception as err:
            self.__logfun(f'请求的链接处理失败：{url}',err)
            header = "HTTP/1.1 400 other error\r\n" + "server:conanServer \r\n" + "\r\n"
            file_data = '<!DOCTYPE html><html><head><meta charset="utf-8"><title>出错啦</title></head><body>未知错误</body></html>'.encode("utf-8")
            content = header.encode("utf-8") + file_data
            newsocket.send(content)
        finally:
             newsocket.close()

    def close_server(self):
        self.__isRun=False
        self.__logfun(f'{self.__port}端口,执行停止此端口的web服务')
        self.__soket_server.close()


    def start_server (self,ip="",port="8888"):
        try:
            self.__soket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.__soket_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
            self.__soket_server.bind((ip, port))
            self.__soket_server.listen(128)
            self.__logfun(f'{self.__port}端口启动新服务成功，访问地址：http://127.0.0.1:{self.__port}')
            while self.__isRun:
                newsocket, ip_port = self.__soket_server.accept()
                newthread = threading.Thread(target=self.hander_reuqest, args=(newsocket, ip_port))
                newthread.setDaemon(True)
                newthread.start()
        except Exception as err:
            self.__logfun(f'{self.__port}端口服务异常',err)
        finally:
            if self.__soket_server :
                self.__soket_server.close()
            self.__logfun(f'{self.__port}端口的web服务停止成功')


    if __name__ == "__main__":
        print(sys.argv)
        port = int(sys.argv[1]) if len(sys.argv)>1 else 8880
        print(port)
        start_server("",port)
